import cv2
import matplotlib.pyplot as plt
import numpy as np
def cv_show(name,image):
    cv2.imshow(name,image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


#### 模板操作
tamplate = cv2.imread('ocr_a_reference.png')
# cv_show('tamplate image',tamplate)

tamplate_gray = cv2.cvtColor(tamplate,cv2.COLOR_BGR2GRAY)
# cv_show('tamplate gray image',tamplate_gray)

_,thresh = cv2.threshold(tamplate_gray,127,255,cv2.THRESH_BINARY_INV)
# cv_show('tamplate 2value image',thresh)

#### 找轮廓
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
draw_tamplate = tamplate.copy()
res = cv2.drawContours(draw_tamplate,contours,-1,(0,0,255),2)
# cv_show('tamplate lunkuo',res)
print('轮廓个数为：',len(contours))

### 轮廓排序,并进行标记
res = []
for cnt in contours:
    x,y,w,h = cv2.boundingRect(cnt)
    res.append((x,y,w,h))
    pic = cv2.rectangle(draw_tamplate,(x,y),(x+w,y+h),(0,255,0),2)
# cv_show('Circumscribed rectangle',pic)
res = sorted(res,key=lambda x:x[0])
print(res)
res_tample = {}
index = 0
for re in res:
    (x,y,w,h) = re
    sample = thresh[y:y+h,x:x+w]
    # cv_show('sample',sample)
    res_tample[index] = sample
    index += 1


##### 原图操作
image = cv2.imread('image/credit_card_02.png')
# cv_show('original image',image)
image_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv_show('gray image',image_gray)
# print(image_gray.shape)

### 闭操作，将数字连在一起
kernel = np.ones((30,30),np.uint8)
closing_image = cv2.morphologyEx(image_gray,cv2.MORPH_CLOSE,kernel)
cv_show('closing image',closing_image)

_,image_thresh = cv2.threshold(closing_image, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# cv_show('image 2value thresh',image_thresh)

image_thresh = cv2.morphologyEx(image_thresh, cv2.MORPH_CLOSE, kernel)
# cv_show('closing image2',image_thresh)


image_contours,_ = cv2.findContours(image_thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
draw_image = image.copy()
image_res = cv2.drawContours(draw_image,image_contours,-1,(0,0,255),2)
cv_show('image lunkuo',image_res)


for cnt in image_contours:
    x,y,w,h = cv2.boundingRect(cnt)
    pic = cv2.rectangle(draw_image,(x,y),(x+w,y+h),(0,255,0),2)
cv_show('image Circumscribed rectangle',pic)

### 筛选矩形
locs = []
for cnt in image_contours:
    x,y,w,h = cv2.boundingRect(cnt)
    print(w,h)
    if w>100 and w<130:
        locs.append((x,y,w,h))
print(len(locs))
draw_image2 = image.copy()
for loc in locs:
    (x,y,w,h) = loc
    pic2 = cv2.rectangle(draw_image2, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv_show('image Circumscribed rectangle2', pic2)

### 矩形排序
locs = sorted(locs,key=lambda x:x[0])
# print(locs)
out = []

### 遍历每一个矩形，并进行模板匹配
for loc in locs:
    (x,y,w,h) = loc
    groupOutput = []
    ## 获取每个区域
    area = image_gray[y-5:y+h+5,x-5:x+w+5]
    # cv_show('area',area)

    group = cv2.threshold(area, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    # cv_show('group', group)
    # cv_show('area 2value ',area_thresh)
    area_contours, hierarchy = cv2.findContours(group,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    draw_area = group.copy()
    area_res = cv2.drawContours(draw_area,area_contours,-1,(0,0,255),1)
    # cv_show('area_lunkuo',area_res)

    ### 区域轮廓排序
    list = []
    for cnt in area_contours:
        x,y,w,h = cv2.boundingRect(cnt)
        list.append((x,y,w,h))
        pic = cv2.rectangle(draw_area,(x,y),(x+w,y+h),(0,255,0),2)
    # cv_show('Circumscribed rectangle',pic)

    list = sorted(list,key=lambda x:x[0])
    # print(list)
    for li in list:
        (x,y,w,h) = li
        sample = area[y:y+h,x:x+w]
        roi = cv2.resize(sample, (55, 86))    #### 这一步非常关键
        # cv_show('roi',roi)
        scores = []
        for key,value in res_tample.items():
            res = cv2.matchTemplate(roi,value,cv2.TM_CCORR_NORMED)
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
            scores.append(max_val)
        groupOutput.append(str(np.argmax(scores)))
    out.extend(groupOutput)
print('银行卡号为：',out)
